﻿using System;
using System.Threading;
using System.IO;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace Space_Conquest
{
    class Helpers
    {

        /// <summary>
        /// Converts ARGB values to a single long value for DirectX Functions
        /// </summary>
        /// <param name="Alpha"></param>
        /// <param name="Red"></param>
        /// <param name="Green"></param>
        /// <param name="Blue"></param>
        /// <returns></returns>
        public static unsafe int ARGB(int Alpha, int Red, int Green, int Blue)
        {

            //long temp = (Blue) + (Green * 256) + (Red * 65536) + (Alpha * 16777216);
            //if (temp > 2147483647) temp -= 4294967296;
            //return (int)temp;
            
            //return System.Drawing.Color.FromArgb(Alpha, Red, Green, Blue).ToArgb();

            return (Blue) + (Green * 256) + (Red * 65536) + (Alpha * 16777216);

        }


        // Only use these methods when debugging
        #if DEBUG

        public static void ClearLog()
        {

            using(StreamWriter sw = new StreamWriter("ErrorLog.txt", false))
            {
                sw.WriteLine("New Error Log Created for Debugging at: " + DateTime.Now.ToString());
                sw.WriteLine("-------------------------------------------------------------------");
                sw.WriteLine();
            }

        }

        public static void LogEvent(string Where, string What)
        {

            using (StreamWriter sw = new StreamWriter("ErrorLog.txt", true))
            {

                sw.WriteLine("-------------------------------------------------------------------");
                sw.WriteLine("------------------------ Error Details ----------------------------");
                sw.WriteLine("-------------------------------------------------------------------");
                sw.WriteLine("Where it Happened");
                sw.WriteLine("\t" + Where);
                sw.WriteLine("");
                sw.WriteLine("What Happened");
                sw.WriteLine("\t" + What);
                sw.WriteLine("-------------------------------------------------------------------");
                sw.WriteLine();
                sw.WriteLine();

            }


        }

        #endif

        public static string ParseKey(string currentText, Keys key, bool shift)
        {

            int intKey = (int)key;

            // Letters
            if ((intKey >= 65 && intKey <= 90))
            {

                if (shift)
                {
                    currentText += (char)intKey;
                }
                else
                {
                    currentText += (char)(intKey + 32);
                }

            }

            // Numbers
            else if ((intKey >= 48 && intKey <= 57))
            {
                currentText += (char)intKey;
            }
                
            // Space
            else if (intKey == 32)
            {
                currentText += (char)intKey;
            }

            else
            {

                switch (key)
                {
                    case Keys.Back:
                        if (currentText.Length > 0)
                        {
                            currentText = currentText.Substring(0, currentText.Length - 1);
                        }
                        break;
                    case Keys.OemPeriod:
                        currentText += ".";
                        break;
                    case Keys.Oemcomma:
                        currentText += ",";
                        break;
                    case Keys.OemQuestion:
                        if(shift)
                            currentText += "?";
                        else
                            currentText += "/";
                        break;
                    default:
                        break;
                }

            }


            return currentText;

        }


        public static bool ValidIPAdress(string ipAddress)
        {

            string[] parts = ipAddress.Split('.');

            if (parts.Length != 4)
                return false;

            foreach (string s in parts)
            {
                int part = Convert.ToInt32(s);
                if (part < 0 || part > 255)
                    return false;
            }

           

            return true;

        }

    }

    

    /// <summary>
    /// Helper Timer class, used to track timing in Game Loop
    /// </summary>
    static class Timer
    {
        /// <summary>
        /// Keeps track of Time that Timer Slept
        /// </summary>
        static private int iLastTickCount = -1;

        /// <summary>
        /// Milliseconds to Sleep when Sleep() is called
        /// </summary>
        static private int iInterval = 40;

        /// <summary>
        /// Milliseconds to Sleep when Sleep() is called (between 10 and 200 milliseconds)
        /// </summary>
        public static int Interval
        {
            get 
            { 
                return iInterval; 
            }
            set 
            {
                if (value < 10)
                    iInterval = 10;
                else if (value > 200)
                    iInterval = 200;
                else
                    iInterval = value;
            }
        }

        /// <summary>
        /// Sleeps for [Timer.Interval] milliseconds, tracks last Sleep for accuracy
        /// </summary>
        public static void Sleep()
        {
            if (iLastTickCount != -1)
            {
                if ((Environment.TickCount - iLastTickCount) < iInterval)
                {
                    Thread.Sleep(iInterval - (Environment.TickCount - iLastTickCount));
                }
                iLastTickCount = Environment.TickCount;
                
            }
            else
            {
                Thread.Sleep(iInterval);
                iLastTickCount = Environment.TickCount;
            }
        }
    }

    /// <summary>
    /// An MD5 wrapper class
    /// </summary>
    static class MD5
    {


        public static string Hash(string input)
        {

            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] hashed = encoding.GetBytes(input);
            hashed = InternalHash(hashed);
            return encoding.GetString(hashed);

        }

        public static string Hash(object input)
        {

            ASCIIEncoding encoding = new ASCIIEncoding();

            return encoding.GetString(InternalHash(Serialize(input)));

        }

        public static string HashFile(string Filename)
        {

            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] data = null;

            using (FileStream fs = new FileStream(Filename, FileMode.Open, FileAccess.Read))
            {
                data = new byte[(int)fs.Length];
                fs.Read(data, 0, (int)fs.Length);
            }

            return encoding.GetString(InternalHash(data));

        }

        static byte[] InternalHash(byte[] byteArray)
        {

            MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
            return MD5.ComputeHash(byteArray);

        }

        static byte[] Serialize(object obj)
        {

            BinaryFormatter binaryFormatter = new BinaryFormatter();
            MemoryStream memoryStream = new MemoryStream();

            binaryFormatter.Serialize(memoryStream, obj);
            memoryStream.Seek(0, SeekOrigin.Begin);
            byte[] arr = new byte[(int)memoryStream.Length];
            memoryStream.Read(arr, 0, (int)memoryStream.Length);

            return arr;

        }


    }


}
